﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using IRCServer.Entities.Commands;
using IRC.Utilities;

namespace IRCServer.Entities
{
    public enum RoutingDaemonCommands
    {
        ADDUSER,
        REMOVEUSER,
        NEXTHOP
    }

    public enum RoutingDaemonResponses
    {
        OK,
        NONE
    }
    /// <summary>
    /// 
    /// </summary>
    public class RoutingDaemon
    {
        Socket routingDaemonSocket;
        byte[] buffer;
        const int maxCommandSize = 1024;

        /// <summary>
        /// Initializes a new instance of the <see cref="RoutingDaemon"/> class.
        /// </summary>
        /// <param name="routerDaemonIPendPoint">The router daemon IP end point.</param>
        public RoutingDaemon(IPEndPoint routerDaemonIpEndPoint)
        {
            this.routingDaemonSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.routingDaemonSocket.Connect(routerDaemonIpEndPoint);
        }

        /// <summary>
        /// Sends the command.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <returns>The daemon response, null if the daemon is disconnected.</returns>
        public string SendCommand(string command)
        {
            Logger.Instance.Debug(string.Format("Sending command '{0}' to routing daemon", command));
            buffer = Encoding.ASCII.GetBytes(command);
            this.routingDaemonSocket.Send(buffer);
            return this.ReceiveResponse();
        }

        /// <summary>
        /// Receives the response.
        /// </summary>
        /// <returns></returns>
        private string ReceiveResponse()
        {
            buffer = new byte[maxCommandSize];
            int length = routingDaemonSocket.Receive(buffer);
            if (length == 0)//Daemon server terminated connection
            {
                Logger.Instance.Debug(string.Format("Received empty response from routing daemon"));
                return null;
            }
            string message = Encoding.ASCII.GetString(buffer, 0, length);
            Logger.Instance.Debug(string.Format("Received response '{0}' from routing daemon", message));
            return message;
        }

        public static string GetCommandName(RoutingDaemonCommands command, string[] parameters)
        {
            switch (command)
            {
                case RoutingDaemonCommands.ADDUSER:
                    if (parameters.Length == 1)
                    {
                        return string.Format("ADDUSER {0}", parameters[0]);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException();
                    }
                case RoutingDaemonCommands.REMOVEUSER:
                    if (parameters.Length == 1)
                    {
                        return string.Format("REMOVEUSER {0}", parameters[0]);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException();
                    }
                case RoutingDaemonCommands.NEXTHOP:
                    if (parameters.Length == 1)
                    {
                        return string.Format("NEXTHOP {0}", parameters[0]);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException();
                    }
                default:
                    return string.Empty;
            }
        }

        public static string GetResponseName(RoutingDaemonResponses response)
        {
            switch (response)
            {
                case RoutingDaemonResponses.NONE:
                    return "NONE";
                case RoutingDaemonResponses.OK:
                    return "OK";
                default:
                    return "Undefined";
            }
        }
    }
}
